﻿'HIDEasy - Test sample
'Copyright (C) 2011 ASFX

'This program is free software; you can redistribute it and/or
'modify it under the terms of the GNU General Public License
'as published by the Free Software Foundation; either version 2
'of the License, or (at your option) any later version.

'This program is distributed in the hope that it will be useful,
'but WITHOUT ANY WARRANTY; without even the implied warranty of
'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'GNU General Public License for more details.

'You should have received a copy of the GNU General Public License
'along with this program; if not, write to the Free Software
'Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
Imports HIDEasy

Public Class FrmReadData
    Private WithEvents _device As HIDDevice

#Region "Variables"
    Private _LastOutputReportSelected As Integer = -2
    Private _LastFeatureReportSelected As Integer = -2
#End Region

#Region "Creators"

    Public Sub New()
        InitializeComponent()
    End Sub

    Public Sub New(ByVal Device As HIDDevice)
        Me.new()
        CheckForIllegalCrossThreadCalls = False

        If Device Is Nothing Then Throw New Exception("Unable to open this form with device=nothing.")

        DataGridViewInputs.AutoGenerateColumns = False
        DataGridViewOutputs.AutoGenerateColumns = False
        DataGridViewFeatures.AutoGenerateColumns = False
        DataGridViewLCN.AutoGenerateColumns = True

        _device = Device
    End Sub

#End Region

#Region "Form Events"

    Private Sub FrmReadData_Load(ByVal sender As Object, _
                                 ByVal e As EventArgs) Handles Me.Load
        '' Init device (like a click on BtnInit)
        'BtnInit_Click(Me, New EventArgs)

        'If _device.IsInit Then
        '    ' Open device (like a click on BtnOpen)
        '    BtnOpen_Click(Me, New EventArgs)
        'End If
        ToolTipHelp.SetToolTip(BtnRefresh, "Refresh")
        ToolTipHelp.SetToolTip(BtnInit, "Init device")
        ToolTipHelp.SetToolTip(BtnClose, "Close device")
        ToolTipHelp.SetToolTip(BtnOpen, "Open device")
        ToolTipHelp.SetToolTip(BtnSendReport, "Send Report(s)")

        Try
            ' Refresh (like a click on BtnRefresh)
            BtnRefresh_Click(Me, New EventArgs)

        Catch ex As Exception
            Dim _e As Exception = ex
            Dim _messages As String = ""

            ' Close the device
            _device.Close()

            ' Display All Exceptions messages.
            Do
                _messages &= _e.GetType.Name & ": " & _e.Message
                _e = _e.InnerException
                If _e Is Nothing Then
                    Exit Do
                Else
                    _messages &= vbCrLf
                End If
            Loop
            MsgBox("Error!" & vbCrLf & _messages, MsgBoxStyle.OkOnly Or MsgBoxStyle.Exclamation, "HIDEasy: Error!")
        End Try

    End Sub

    Private Sub FrmReadData_FormClosing(ByVal sender As Object, _
                                        ByVal e As FormClosingEventArgs) Handles Me.FormClosing
        If DataGridViewInputs.IsCurrentRowDirty AndAlso _
           Not DataGridViewInputs.CancelEdit() Then
            e.Cancel = True
            Exit Sub
        ElseIf DataGridViewOutputs.IsCurrentRowDirty AndAlso _
               Not DataGridViewOutputs.CancelEdit() Then
            e.Cancel = True
            Exit Sub
        ElseIf DataGridViewFeatures.IsCurrentRowDirty AndAlso _
               DataGridViewFeatures.CancelEdit() Then
            e.Cancel = True
            Exit Sub
        End If

        DataGridViewInputs.DataSource = Nothing
        DataGridViewOutputs.DataSource = Nothing
        DataGridViewFeatures.DataSource = Nothing

        _device.Close()
        _device.Dispose()
        _device = Nothing
    End Sub

#End Region

#Region "Properties"

    Public ReadOnly Property HIDDevice As HIDDevice
        Get
            Return _device
        End Get
    End Property

#End Region

#Region "DataGrids Events"

    Private Sub DataGridViewInputs_CellFormatting(ByVal sender As Object, _
                                                  ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) _
        Handles DataGridViewInputs.CellFormatting
        LogicalValueCellFormating(DataGridViewInputs, Input_LogicalValue, e)
    End Sub

    Private Sub DataGridViewOutputs_CellFormatting(ByVal sender As Object, _
                                                   ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) _
        Handles DataGridViewOutputs.CellFormatting
        LogicalValueCellFormating(DataGridViewOutputs, Output_LogicalValue, e)
    End Sub

    Private Sub DataGridViewOutputs_CellValidating(ByVal sender As Object, _
                                                   ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) _
        Handles DataGridViewOutputs.CellValidating
        LogicalValueCellValidating(DataGridViewOutputs, Output_LogicalValue, e)
    End Sub

    Private Sub DataGridViewFeatures_CellFormatting(ByVal sender As Object, _
                                                    ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) _
        Handles DataGridViewFeatures.CellFormatting
        LogicalValueCellFormating(DataGridViewFeatures, Feature_LogicalValue, e)
    End Sub

    Private Sub DataGridViewFeatures_CellValidating(ByVal sender As Object, _
                                                    ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) _
        Handles DataGridViewFeatures.CellValidating
        LogicalValueCellValidating(DataGridViewFeatures, Feature_LogicalValue, e)
    End Sub

    Private Sub LogicalValueCellFormating(ByVal DGV As DataGridView, _
                                          ByVal ColunmLogicalValue As DataGridViewTextBoxColumn, _
                                          ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs)
        If DGV.Columns(e.ColumnIndex).Name = ColunmLogicalValue.Name Then
            Dim _CellLogicalValue As DataGridViewCell = DGV.Rows(e.RowIndex).Cells(ColunmLogicalValue.Name)

            ' Get the HIDItem displayed by this row
            Dim _item As HIDItem = CType(DGV.Rows(e.RowIndex).DataBoundItem, HIDItem)
            SyncLock _item.SyncRoot
                If _item.ValueExists Then
                    '_CellLogicalValue.ErrorText = ""
                    e.Value = _item.LogicalValue
                Else
                    If _item.HasNull Then
                        '_CellLogicalValue.ErrorText = ""
                        e.Value = "null"
                    Else
                        '_CellLogicalValue.ErrorText = "[No value]"
                        e.Value = "[No value]"
                    End If
                End If
            End SyncLock
        End If
    End Sub

    Private Sub LogicalValueCellValidating(ByVal DGV As DataGridView, _
                                           ByVal ColunmLogicalValue As DataGridViewTextBoxColumn, _
                                           ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs)

        If DGV.Columns(e.ColumnIndex).Name = ColunmLogicalValue.Name Then
            Dim _
                _CellLogicalValue As DataGridViewTextBoxCell = _
                    CType(DGV.Rows(e.RowIndex).Cells(ColunmLogicalValue.Name), DataGridViewTextBoxCell)

            ' Get the HIDItem displayed by this row
            Dim _item As HIDItem = CType(DGV.Rows(e.RowIndex).DataBoundItem, HIDItem)
            SyncLock _item.SyncRoot
                ' Get the current value of the cell
                Dim _CurrentValue As String = CStr(e.FormattedValue)
                If String.IsNullOrEmpty(_CurrentValue) Then
                    Try
                        _item.LogicalValue = _item.LogicalMax + 1
                    Catch exMax As OverflowException
                        Try
                            _item.LogicalValue = _item.LogicalMin - 1
                        Catch exMin As OverflowException
                            e.Cancel = True
                            _CellLogicalValue.ErrorText = _
                                String.Format("Unable to set null value ({0}).", exMin.Message)
                        End Try
                    End Try
                Else
                    If IsNumeric(_CurrentValue) Then
                        Try
                            _item.LogicalValue = CInt(_CurrentValue)
                        Catch ex As Exception
                            e.Cancel = True
                            _CellLogicalValue.ErrorText = String.Format("Unable to set value ({0}).", ex.Message)
                        End Try
                    Else
                        _CellLogicalValue.ErrorText = "Enter a numerical value, or an empty text for null."
                    End If
                End If
            End SyncLock
        End If
    End Sub

    Private Sub DataGridViewInputs_DataError(ByVal sender As Object, _
                                             ByVal e As DataGridViewDataErrorEventArgs)

        If DataGridViewInputs.Columns(e.ColumnIndex).Name = Input_LogicalValue.Name Then
            ' Get the cell
            Dim _
                _CellLogicalValue As DataGridViewCell = _
                    DataGridViewInputs.Rows(e.RowIndex).Cells(Input_LogicalValue.Name)

            ' Get the HIDItem displayed by this row
            Dim _item As HIDItem = CType(DataGridViewInputs.Rows(e.RowIndex).DataBoundItem, HIDItem)
            If _item.HasNull Then
                ' HIDItem has null
                _CellLogicalValue.ErrorText = "<Null>"
            Else
                ' HIDItem has no data
                _CellLogicalValue.ErrorText = "<Waiting a first value>"
            End If
        Else
            e.ThrowException = True
        End If
    End Sub

#End Region

#Region "HIDDevice events"

    Private Sub OnDevice_Closed(ByVal sender As Object, _
                                ByVal e As HIDDeviceClosedEventArgs) Handles _device.Closed
        If e.Exception IsNot Nothing Then
            AddEventInformation("Device Closed with error:")
            ' Display All Exceptions messages.
            Dim _e As Exception = e.Exception
            Do
                AddEventInformation(_e.GetType.Name & ": " & _e.Message)
                _e = _e.InnerException
                If _e Is Nothing Then
                    Exit Do
                End If
            Loop
        Else
            AddEventInformation("Device Closed.")
        End If
        BtnInit.Enabled = Not _device.IsInit
        BtnOpen.Enabled = True
        BtnClose.Enabled = False
    End Sub

    Private Sub OnDevice_Removed(ByVal sender As Object, _
                                 ByVal e As HIDDeviceRemovedEventArgs) Handles _device.Removed

        If e.Exception IsNot Nothing Then
            AddEventInformation("Device Removed with error:")
            ' Display All Exceptions messages.
            Dim _e As Exception = e.Exception
            Do
                AddEventInformation(_e.GetType.Name & ": " & _e.Message)
                _e = _e.InnerException
                If _e Is Nothing Then
                    Exit Do
                End If
            Loop
        Else
            AddEventInformation("Device Removed.")
        End If
        RefreshControls()
    End Sub

    Private Sub OnDevice_HIDDeviceItemChanged(ByVal sender As Object, _
                                              ByVal e As HIDDeviceItemChangedEventArgs) _
        Handles _device.HIDDeviceItemChanged
        Select Case e.ReportType
            Case HIDReport.ReportType.Input
                For Each _row As DataGridViewRow In DataGridViewInputs.Rows
                    If e.ItemChanged.Equals(_row.DataBoundItem) Then
                        DataGridViewInputs.UpdateCellValue(DataGridViewInputs.Columns("Input_LogicalValue").Index, _
                                                           _row.Index)
                    End If
                Next
            Case HIDReport.ReportType.Output
                For Each _row As DataGridViewRow In DataGridViewOutputs.Rows
                    If e.ItemChanged.Equals(_row.DataBoundItem) Then
                        DataGridViewOutputs.UpdateCellValue(DataGridViewOutputs.Columns("Output_LogicalValue").Index, _
                                                            _row.Index)
                        If Output_HasChanged.Visible Then
                            DataGridViewOutputs.UpdateCellValue(DataGridViewOutputs.Columns("Output_HasChanged").Index, _
                                                                _row.Index)
                        End If
                    End If
                Next
            Case HIDReport.ReportType.Feature
                For Each _row As DataGridViewRow In DataGridViewFeatures.Rows
                    If e.ItemChanged.Equals(_row.DataBoundItem) Then
                        DataGridViewFeatures.UpdateCellValue(DataGridViewFeatures.Columns("Feature_LogicalValue").Index, _
                                                             _row.Index)
                        If Feature_HasChanged.Visible Then
                            DataGridViewFeatures.UpdateCellValue( _
                                                                 DataGridViewFeatures.Columns("Feature_HasChanged"). _
                                                                    Index, _
                                                                 _row.Index)
                        End If
                    End If
                Next
        End Select
    End Sub

    Private Sub OnDevice_HIDDeviceReportReceived(ByVal sender As Object, _
                                                 ByVal e As HIDDeviceReportReceivedEventArgs) _
        Handles _device.HIDDeviceReportReceived
        AddEventInformation(e.newReport.ToString)
    End Sub

#End Region

#Region "Update Informations"

    Private Delegate Sub AddNewInputReportsCallBack(ByVal text As String)

    Private Sub AddEventInformation(ByVal text As String)
        If Me.InvokeRequired Then
            Dim d As New AddNewInputReportsCallBack(AddressOf AddEventInformation)
            If Not Me.IsDisposed Then
                Me.BeginInvoke(d, New Object() {text})
            End If
            Exit Sub
        End If

        Dim _str As String
        Dim _dte As Date = Date.Now
        _str = _dte.ToLongTimeString & "." & _dte.Millisecond.ToString("D3") & "->" & text

        With ListBoxEvents
            .BeginUpdate()
            Try
                ' Remove Lines if too long (better performance)
                If .Items.Count > 60 Then
                    Do While .Items.Count >= 50
                        .Items.RemoveAt(0)
                    Loop
                End If
                ' add text
                .Items.Add(_str)
                .SelectedIndex = .Items.Count - 1
            Finally
                .EndUpdate()
            End Try
        End With
        With LblInformations
            .Text = _str
        End With
    End Sub

#End Region

#Region "Buttons Refresh/Open/Close/TabPages"

    Private Sub BtnRefresh_Click(ByVal sender As Object, _
                                 ByVal e As EventArgs) Handles BtnRefresh.Click

        RefreshDatas()
        RefreshControls()
    End Sub

    Private Sub BtnOpen_Click(ByVal sender As Object, _
                              ByVal e As EventArgs) Handles BtnOpen.Click
        ' Open the device
        Try
            _device.Open()
            AddEventInformation("Device Open.")
        Catch ex As Exception
            ' Close the device
            _device.Close()

            ExceptionMsgBox("Error on Open!", MsgBoxStyle.OkOnly Or MsgBoxStyle.Exclamation, "HIDEasy: Error!", ex)
        End Try
        RefreshDatas()
        RefreshControls()
    End Sub

    Private Sub BtnClose_Click(ByVal sender As Object, _
                               ByVal e As EventArgs) Handles BtnClose.Click
        ' Open the device
        Try
            _device.Close()
            AddEventInformation("Device Close.")
        Catch ex As Exception
            Dim _e As Exception = ex
            Dim _messages As String = ""

            ' Display All Exceptions messages.
            Do
                _messages &= _e.GetType.Name & ": " & _e.Message
                _e = _e.InnerException
                If _e Is Nothing Then
                    Exit Do
                Else
                    _messages &= vbCrLf
                End If
            Loop
            MsgBox("Error on Close!" & vbCrLf & _messages, MsgBoxStyle.OkOnly Or MsgBoxStyle.Exclamation, _
                   "HIDEasy: Error!")
        End Try
        RefreshDatas()
        RefreshControls()
    End Sub

    Private Sub BtnInit_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) Handles BtnInit.Click
        ' Init HIDItem
        Try
            _device.InitHIDItems()
            AddEventInformation("Device Init.")
        Catch ex As Exception
            Dim _e As Exception = ex
            Dim _messages As String = ""

            ' Display All Exceptions messages.
            Do
                _messages &= _e.GetType.Name & ": " & _e.Message
                _e = _e.InnerException
                If _e Is Nothing Then
                    Exit Do
                Else
                    _messages &= vbCrLf
                End If
            Loop
            MsgBox("Error on Init!" & vbCrLf & _messages, MsgBoxStyle.OkOnly Or MsgBoxStyle.Exclamation, _
                   "HIDEasy: Error!")
        End Try
        RefreshDatas()
        RefreshControls()
    End Sub

    Private Sub TabControl1_SelectedIndexChanged(ByVal sender As Object, _
                                                 ByVal e As System.EventArgs) Handles TabControl1.SelectedIndexChanged
        RefreshControls()
    End Sub

    Private Sub BtnSendReport_Click(sender As Object, _
                                    e As System.EventArgs) Handles BtnSendReport.Click
        Dim _HIDItemCol As HIDItemCollection = Nothing
        If TabControl1.SelectedTab.Equals(TabPageOutput) Then
            _HIDItemCol = _device.OutputItems
        ElseIf TabControl1.SelectedTab.Equals(TabPageFeatures) Then
            _HIDItemCol = _device.FeatureItems
        Else
            Exit Sub
        End If
        Dim _ReportList As New List(Of Byte)
        Try
            Select Case CType(ComboBoxReportsToSend.SelectedItem, ReportIDItem).ID
                Case -1
                    'Send All Reports
                    For Each _reportID As Byte In HIDItemCollection.GetReportIDs(_HIDItemCol)
                        If Not _ReportList.Contains(_reportID) Then
                            _ReportList.Add(_reportID)
                        End If
                    Next
                Case -2
                    'Send Modified reports
                    For Each _item As HIDItem In _HIDItemCol
                        If _item.HasChanged Then
                            If Not _ReportList.Contains(_item.ReportID) Then
                                _ReportList.Add(_item.ReportID)
                            End If
                        End If
                    Next
                Case Else
                    'Send selected Report 
                    _ReportList.Add(CType(CType(ComboBoxReportsToSend.SelectedItem, ReportIDItem).ID, Byte))
            End Select
        Catch ex As Exception
            ExceptionMsgBox("Error!", MsgBoxStyle.OkOnly Or MsgBoxStyle.Exclamation, "HIDEasy: Error!", ex)
            RefreshControls()
            Exit Sub
        End Try

        If _ReportList.Count = 0 Then
            MsgBox("No Report To send!", MsgBoxStyle.OkOnly Or MsgBoxStyle.Information, "HIDEasy:")
        Else
            If TabControl1.SelectedTab.Equals(TabPageOutput) Then
                Try
                    For Each _ReportID As Byte In _ReportList
                        _device.WriteOutputReport(_ReportID)
                    Next
                Catch ex As Exception
                    ExceptionMsgBox("Error on send an OutputReport!", MsgBoxStyle.OkOnly Or MsgBoxStyle.Exclamation, _
                                    "HIDEasy: Error!", ex)
                    RefreshControls()
                End Try

            ElseIf TabControl1.SelectedTab.Equals(TabPageFeatures) Then
                Try
                    For Each _ReportID As Byte In _ReportList
                        _device.WriteFeatureReport(_ReportID)
                    Next
                Catch ex As Exception
                    ExceptionMsgBox("Error on send a FeatureReport!", MsgBoxStyle.OkOnly Or MsgBoxStyle.Exclamation, _
                                    "HIDEasy: Error!", ex)
                    RefreshControls()
                End Try
            End If
        End If
    End Sub

    Private Sub ComboBoxReportsToSend_SelectedIndexChanged(sender As Object, _
                                                           e As System.EventArgs) _
        Handles ComboBoxReportsToSend.SelectedIndexChanged
        If TabControl1.SelectedTab.Equals(TabPageOutput) Then
            _LastOutputReportSelected = CType(ComboBoxReportsToSend.SelectedItem, ReportIDItem).ID
        ElseIf TabControl1.SelectedTab.Equals(TabPageFeatures) Then
            _LastFeatureReportSelected = CType(ComboBoxReportsToSend.SelectedItem, ReportIDItem).ID
        End If
    End Sub

    Private Sub RefreshDatas()
        ' Set Form Text
        Me.Text = _device.Description

        ' Display HIDDevice properties
        PropertyGridDevice.SelectedObject = Nothing
        PropertyGridDevice.SelectedObject = _device

        ' Get Informations
        TextBoxInformations.Text = _device.GetInformations

        If _device.IsInit Then
            ' Populate Inputs HIDItems
            With DataGridViewInputs
                '.DataSource = Nothing
                .DataSource = _device.InputItems
            End With
            ' Populate Outputs HIDItems
            With DataGridViewOutputs
                '.DataSource = Nothing
                .DataSource = _device.OutputItems
            End With
            ' Populate Features HIDItems
            With DataGridViewFeatures
                '.DataSource = Nothing
                .DataSource = _device.FeatureItems
            End With
            ' Populate Link Collection Nodes
            With DataGridViewLCN
                '.DataSource = Nothing
                .DefaultCellStyle.BackColor = Color.FromArgb(255, 224, 224, 224)
                .DataSource = _device.LinkCollectionNode
            End With
        Else
            ' No Inputs HIDItems
            With DataGridViewInputs
                .DataSource = Nothing
            End With
            ' No Outputs HIDItems
            With DataGridViewOutputs
                .DataSource = Nothing
            End With
            ' No Features HIDItems
            With DataGridViewFeatures
                .DataSource = Nothing
            End With
            ' No Link Collection Nodes
            With DataGridViewLCN
                .DataSource = Nothing
            End With
        End If
    End Sub

    Private Sub RefreshControls()

        If _device IsNot Nothing AndAlso _device.IsInit Then
            BtnInit.Enabled = False
            If _device.IsOpen Then
                BtnOpen.Enabled = False
                BtnClose.Enabled = True
            Else
                BtnOpen.Enabled = True
                BtnClose.Enabled = False
            End If
            Dim _HIDItemCol As HIDItemCollection = Nothing
            If TabControl1.SelectedTab.Equals(TabPageOutput) Then
                _HIDItemCol = _device.OutputItems
            ElseIf TabControl1.SelectedTab.Equals(TabPageFeatures) Then
                _HIDItemCol = _device.FeatureItems
            Else
                _HIDItemCol = Nothing
            End If

            If _device.WriteReportMethod = HIDEasy.HIDDevice.WriteReportMethodType.ByCallWriteReport _
               And _HIDItemCol IsNot Nothing Then

                SplitContainerDataAndWriteReport.Panel2Collapsed = False
                ComboBoxReportsToSend.Items.Clear()
                'Populate reports to send
                ComboBoxReportsToSend.Items.Add(New ReportIDItem(-1, "All Reports"))
                ComboBoxReportsToSend.Items.Add(New ReportIDItem(-2, "All Modified Reports"))
                For Each _reportID As Byte In HIDItemCollection.GetReportIDs(_HIDItemCol)
                    ComboBoxReportsToSend.Items.Add(New ReportIDItem(_reportID, _reportID.ToString))
                Next
                If ComboBoxReportsToSend.Items.Count > 2 Then
                    ComboBoxReportsToSend.Enabled = True
                    BtnSendReport.Enabled = True
                Else
                    ComboBoxReportsToSend.Enabled = False
                    BtnSendReport.Enabled = False
                End If
                Output_HasChanged.Visible = True
                Feature_HasChanged.Visible = True

                Dim _Isfound As Boolean = False
                If TabControl1.SelectedTab.Equals(TabPageOutput) Then
                    For Each _Item As Object In ComboBoxReportsToSend.Items
                        If CType(_Item, ReportIDItem).ID = _LastOutputReportSelected Then
                            ComboBoxReportsToSend.SelectedItem = _Item
                            _Isfound = True
                            Exit For
                        End If
                    Next
                    If Not _Isfound Then
                        ComboBoxReportsToSend.SelectedIndex = 1
                    End If
                ElseIf TabControl1.SelectedTab.Equals(TabPageFeatures) Then
                    For Each _Item As Object In ComboBoxReportsToSend.Items
                        If CType(_Item, ReportIDItem).ID = _LastFeatureReportSelected Then
                            ComboBoxReportsToSend.SelectedItem = _Item
                            Exit For
                        End If
                    Next
                    If Not _Isfound Then
                        ComboBoxReportsToSend.SelectedIndex = 1
                    End If
                End If
            Else
                SplitContainerDataAndWriteReport.Panel2Collapsed = True
                ComboBoxReportsToSend.Items.Clear()
                ComboBoxReportsToSend.Enabled = False
                BtnSendReport.Enabled = False

                Output_HasChanged.Visible = False
                Feature_HasChanged.Visible = False
            End If
        Else
            BtnInit.Enabled = True
            BtnOpen.Enabled = False
            BtnClose.Enabled = False
            SplitContainerDataAndWriteReport.Panel2Collapsed = True
            ComboBoxReportsToSend.Items.Clear()
            ComboBoxReportsToSend.Enabled = False
            BtnSendReport.Enabled = False
        End If
    End Sub

#End Region

#Region "Misc"

    Private Function ExceptionMsgBox(message As String, _
                                     Buttons As MsgBoxStyle, _
                                     Title As Object, _
                                     ex As Exception) As MsgBoxResult
        ' Display All Exceptions messages.
        Dim _e As Exception = ex
        Dim _messages As String = message & vbCrLf

        Do
            _messages &= _e.GetType.Name & ": " & _e.Message
#If DEBUG Then
            _messages &= vbCrLf
            _messages &= "Source: " & _e.Source & vbCrLf
            _messages &= "StackTrace: " & _e.GetType.Name & " " & _e.StackTrace
#End If
            _e = _e.InnerException
            If _e Is Nothing Then
                Exit Do
            Else
                _messages &= vbCrLf
            End If
        Loop
        Return MsgBox(_messages, Buttons, Title)
    End Function

    Private Class ReportIDItem
        Private _ID As Integer
        Private _Text As String

        Public Sub New(ID As Integer, _
                       Text As String)
            _ID = ID
            _Text = Text
        End Sub

        Public ReadOnly Property ID As Integer
            Get
                Return _ID
            End Get
        End Property

        Public ReadOnly Property Text As String
            Get
                Return _Text
            End Get
        End Property

        Public Overrides Function ToString() As String
            Return _Text
        End Function
    End Class

#End Region
End Class